%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#ifndef YYSTYPE
// 定义类型为字符指针
#define YYSTYPE char*
#endif

int yylex();
extern int yyparse();
FILE* yyin;
void yyerror(const char* s);

%}


%token NUMBER
%token ID //标识符
%token ADD
%token SUB
%token MUL
%token DIV
%token LB
%token RB
//优先级
%left ADD SUB
%left MUL DIV
%right UMINUS 

//规则段
%%

lines :    lines expr ';' { printf("%s\n", $2); } 
      |    lines ';'
      |
      ;

expr  :    expr ADD term  { $$ = (char*)malloc(50*sizeof(char)); strcpy($$,$1); strcat($$," "); strcat($$,$3); strcat($$,"+"); }  //加法
      |    expr SUB term  { $$ = (char*)malloc(50*sizeof(char)); strcpy($$,$1); strcat($$," "); strcat($$,$3); strcat($$,"- "); } //减法
      |    term                  
      ;

term  :    term MUL factor  { $$ = (char*)malloc(50*sizeof(char)); strcpy($$,$1); strcat($$," "); strcat($$,$3); strcat($$,"* "); }//乘法
      |    term DIV factor  { $$ = (char*)malloc(50*sizeof(char)); strcpy($$,$1); strcat($$," "); strcat($$,$3); strcat($$,"/ "); }//除法
      |    factor         
      ;

factor  :    LB expr RB   { $$ = $2; }  
        |    SUB  factor %prec UMINUS  { $$ = (char*)malloc(50*sizeof(char)); strcpy($$,"- "); strcat($$,$2); } //负数
        |    NUMBER         { $$ = (char*)malloc(50*sizeof(char)); strcpy($$,$1); strcat($$," "); }
        |    ID             { $$ = (char*)malloc(50*sizeof(char)); strcpy($$,$1); strcat($$," "); }
        ;
%%


int yylex()
{
    int t;
    while(1){
        t=getchar();
        if(t==' ' || t=='\t'||t=='\n')
            {
            }   
	else if ( (t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z') || (t == '_')) { 
	    char str[256];
	    int val = 0;
	    int isstay = 1; 
	    
	    while ((t >= '0' && t <= '9') || (t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z') || (t == '_')) 
	    {
		str[val] = t;
		if (t < '0' || (t > '9' && t < 'A') || (t > 'Z' && t < 'a') || (t > 'z')) 
		{
		    isstay = 0;
		}
		val++;
		t = getchar();
	    }
	    str[val] = '\0';
		ungetc(t, stdin);   
	    yylval = str;
	    if (isstay ) 
	    {
		return NUMBER;
	    }
	    return ID;
	}
        else if(t=='+') {
            return ADD;  
        }
        else if(t=='-'){
            return SUB;
        }
        else if(t=='*'){
            return MUL;
        }
        else if(t=='/'){
            return DIV;
        }
        else if(t=='('){
            return LB;
        }
        else if(t==')'){
            return RB;
        }
        else {
            return t;
        }
    }
}

int main(void)
{
    yyin = stdin;
    do{
        yyparse();
    } while(!feof(yyin));
    return 0;
}
void yyerror(const char* s){
    fprintf(stderr, "Parse error: %s\n", s);
    exit(1);
    }
